package gptma.fo.cdi;

import java.lang.annotation.Annotation;
import java.util.Map;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.faces.context.FacesContext;

/**
 * 
 * @author xcl
 * @see http 
 *      ://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation
 *      -to-cdi/
 */
public class ViewContext implements Context {

	@Override
	public Class<? extends Annotation> getScope() {
		return ViewScoped.class;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T get(Contextual<T> contextual,
			CreationalContext<T> creationalContext) {
		T ret = null;

		Bean<T> bean = (Bean<T>) contextual;
		String name = bean.getName();
		Map<String, Object> map = getViewMap();
		if (map.containsKey(name)) {
			ret = (T) map.get(name);
		} else {
			ret = bean.create(creationalContext);
			map.put(name, ret);
		}

		return ret;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T get(Contextual<T> contextual) {
		Bean<T> bean = (Bean<T>) contextual;
		Map<String, Object> map = getViewMap();

		return (T) map.get(bean.getName());
	}

	@Override
	public boolean isActive() {
		return true;
	}

	private Map<String, Object> getViewMap() {
		return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
	}

}
